import 'package:flutter/services.dart';
import 'package:usbflutter/usb/HandlerFactory.dart';
import 'package:usbflutter/usb/UsbItem.dart';
import 'package:usbflutter/usb/UsbResult.dart';
import 'package:usbflutter/usb/handler/IDevicceHandler.dart';

import 'UsbPackage.dart';

typedef OnNewData = void Function(UsbPackage data);
typedef OnSelectHandler = IDeviceHandler Function(int vendor, int product);

class DataSubscribe {
  int deviceId;
  OnNewData listener;

  DataSubscribe(this.deviceId, this.listener);
}

class UsbManager {
  static const platform = MethodChannel('yichen_usb');

  static UsbManager instance = UsbManager._();

  UsbManager._();

  List<UsbItem> usbList = [];
  OnSelectHandler? onSelectHandler;

  Map<int, IDeviceHandler> handlerMap = {};
  List<DataSubscribe> subscribeList = [];

  void init() {
    platform.setMethodCallHandler(_methodHandler);
  }

  /// 订阅
  void subscribe(int deviceId, OnNewData listener) {
    subscribeList.add(DataSubscribe(deviceId, listener));
  }

  /// 取消数据订阅
  void unsubscribe(int deviceId, OnNewData listener) {
    for (var item in subscribeList) {
      if (item.deviceId == deviceId && item.listener == listener) {
        subscribeList.remove(item);
        break;
      }
    }
  }

  /// 连接设备
  Future<UsbResult> connect(int deviceId) async {
    UsbItem? usbItem;
    for (final item in usbList) {
      if (item.deviceId == deviceId) {
        usbItem = item;
        break;
      }
    }
    if (usbItem == null) {
      return UsbResult(-1, "设备不存在!");
    }
    var handler =
        HandlerFactory.create(usbItem.vendorId, usbItem.productId);
    if (handler == null && onSelectHandler != null) {
      handler = onSelectHandler!(usbItem.vendorId, usbItem.productId);
    }
    handler ??= IDeviceHandler();
    final data = await platform.invokeMethod(
        "connectDevice", {'deviceId': deviceId, 'baudRate': handler.baudRate});
    final result = UsbResult.parse(data);
    if (result.code == 0) {
      handlerMap[deviceId] = handler;
    }
    return result;
  }

  /// 断开连接
  Future<UsbResult> disconnect(int deviceId) async {
    final data =
        await platform.invokeMethod("disconnectDevice", {'deviceId': deviceId});
    final result = UsbResult.parse(data);
    if (result.code == 0) {
      handlerMap.remove(deviceId);
    }
    return result;
  }

  /// 查找设别
  Future<List<UsbItem>> findDevice() async {
    final data = await platform.invokeMethod("findDevices");
    List<UsbItem> list = [];
    for (final item in data) {
      list.add(UsbItem.parse(item));
    }
    usbList = list;
    return list;
  }

  /// 设备数据处理
  Future _methodHandler(MethodCall call) {
    final method = call.method;
    if (method == 'onDeviceData') {
      final data = call.arguments;
      final package = UsbPackage.parse(data);
      _handle(package);
      return Future.value(null);
    }
    if (method == 'onDeviceDisconnect') {
      final data = call.arguments;
      final package = UsbPackage.parse(data);
      package.event = UsbPackage.DISCONNECT;
      _handle(package);
      return Future.value(null);
    }
    if (method == 'onUsbPermission') {
      final data = call.arguments;
      final package = UsbPackage.parse(data);
      package.event = UsbPackage.USB_PERMISSION;
      _handle(package);
    }
    return Future.value(null);
  }

  /// 数据交给处理器处理
  void _handle(UsbPackage package) {
    final handler = handlerMap[package.deviceId];
    if (handler != null) {
      handler.onNewData(package);
      package.handler = handler;
    }
    for (var item in subscribeList) {
      if (package.deviceId == -1 || item.deviceId == package.deviceId) {
        item.listener(package);
      }
    }
  }


  /// 设置处理器
  void setHandlerSelector(OnSelectHandler onSelectHandler) {
    this.onSelectHandler = onSelectHandler;
  }

}
